﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.IO;
using Microsoft.Win32;
using System.Data.SQLite;
using System.Data;
using System.Net;
using System.Diagnostics;
using System.Collections.ObjectModel;

namespace NUMIMAX
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Pola
        private string databaseName = null;
        private bool canBeSaved = false;
        private ObservableCollection<Coin> loadedCoins = new ObservableCollection<Coin>();
        private CommandBinding newFileBinding = new CommandBinding(ApplicationCommands.New);
        private CommandBinding openFileBinding = new CommandBinding(ApplicationCommands.Open);
        private CommandBinding saveFileBinding = new CommandBinding(ApplicationCommands.Save);
        private CommandBinding exitApplicationBinding = new CommandBinding(ApplicationCommands.Close);
        private CommandBinding printBinding = new CommandBinding(ApplicationCommands.Print);
        private CommandBinding printPreviewBinding = new CommandBinding(ApplicationCommands.PrintPreview);
        private CommandBinding helpBinding = new CommandBinding(ApplicationCommands.Help);
        private CommandBinding searchBinding = new CommandBinding(ApplicationCommands.Find);
        private CommandBinding browceBackBinding = new CommandBinding(NavigationCommands.BrowseBack);
        private CommandBinding firstPageBinding = new CommandBinding(NavigationCommands.FirstPage);
        private CommandBinding settingsBinding = new CommandBinding(Command.Settings);
        private CommandBinding reportBinding = new CommandBinding(Command.Report);
        private CommandBinding downloadDatabaseBinding = new CommandBinding(Command.DownloadDatabase);
        private CommandBinding uploadDatabaseBinding = new CommandBinding(Command.SaveDatabase);
        private CommandBinding eksportBinding = new CommandBinding(Command.Eksport);
        private CommandBinding importDatabaseBinding = new CommandBinding(Command.ImportDatabase);
        private CommandBinding aboutBinding = new CommandBinding(Command.About);
        private CommandBinding registerBinding = new CommandBinding(Command.Register);
        private CommandBinding recentlyUsedBinding = new CommandBinding(Command.RecentlyUsed);
        private CommandBinding storageReportBinding = new CommandBinding(Command.StorageReport);
        private CommandBinding allCardsBinding = new CommandBinding(Command.AllCards);
        private CommandBinding saveDatabaseBinding = new CommandBinding(Command.SaveDatabase);
        private CommandBinding addCoinBinding = new CommandBinding(Command.AddCoin);
        private CommandBinding addFolderBinding = new CommandBinding(Command.AddFolder);
        private CommandBinding renameFolderBinding = new CommandBinding(Command.RenameFolder);
        private CommandBinding deleteFolderBinding = new CommandBinding(Command.DeleteFolder);
        public SetParameterValueDelegate SetParameterValueCallback;
        public SetParameterValueDelegate SetParameterValueCallbackDodajMonete;
        private int[] tablicaCheckBox = new int[19];
        #endregion

        public ObservableCollection<Coin> CoinsCollection
        {
            get { return loadedCoins; }
        }

        public MainWindow()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            newFileBinding.Executed += new ExecutedRoutedEventHandler(newFile_Executed);
            openFileBinding.Executed += new ExecutedRoutedEventHandler(openFile_Executed);
            saveFileBinding.Executed += new ExecutedRoutedEventHandler(saveFile_Executed);
            exitApplicationBinding.Executed += new ExecutedRoutedEventHandler(closeApplication_Executed);
            helpBinding.Executed += new ExecutedRoutedEventHandler(showHelp_Executed);
            printPreviewBinding.Executed += new ExecutedRoutedEventHandler(printPreview_Executed);
            printBinding.Executed += new ExecutedRoutedEventHandler(print_Executed);
            settingsBinding.Executed += new ExecutedRoutedEventHandler(settings_Executed);
            reportBinding.Executed += new ExecutedRoutedEventHandler(reportBinding_Executed);
            downloadDatabaseBinding.Executed += new ExecutedRoutedEventHandler(downloadDatabaseBinding_Executed);
            uploadDatabaseBinding.Executed += new ExecutedRoutedEventHandler(uploadDatabaseBinding_Executed);
            eksportBinding.Executed += new ExecutedRoutedEventHandler(eksportBinding_Executed);
            importDatabaseBinding.Executed += new ExecutedRoutedEventHandler(importDatabaseBinding_Executed);
            aboutBinding.Executed += new ExecutedRoutedEventHandler(aboutBinding_Executed);
            registerBinding.Executed += new ExecutedRoutedEventHandler(registerBinding_Executed);
            recentlyUsedBinding.Executed += new ExecutedRoutedEventHandler(recentlyUsedBinding_Executed);
            storageReportBinding.Executed += new ExecutedRoutedEventHandler(storageReportBinding_Executed);
            allCardsBinding.Executed += new ExecutedRoutedEventHandler(allCardsBinding_Executed);
            saveDatabaseBinding.Executed += new ExecutedRoutedEventHandler(saveDatabase_Executed);
            addCoinBinding.Executed += new ExecutedRoutedEventHandler(addCoinBinding_Executed);
            addFolderBinding.Executed += new ExecutedRoutedEventHandler(addFolderBinding_Executed);
            renameFolderBinding.Executed += new ExecutedRoutedEventHandler(renameFolderBinding_Executed);
            deleteFolderBinding.Executed +=new ExecutedRoutedEventHandler(deleteFolderBinding_Executed);
            this.CommandBindings.Add(exitApplicationBinding);
            this.CommandBindings.Add(newFileBinding);
            this.CommandBindings.Add(openFileBinding);
            this.CommandBindings.Add(helpBinding);
            this.CommandBindings.Add(settingsBinding);
            this.CommandBindings.Add(downloadDatabaseBinding);
            this.CommandBindings.Add(uploadDatabaseBinding);
            this.CommandBindings.Add(reportBinding);
            this.CommandBindings.Add(storageReportBinding);
            this.CommandBindings.Add(saveDatabaseBinding);
            watek_ladowanie_danych_podstawowych();
        }

        void deleteFolderBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }
        
        void renameFolderBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        void addFolderBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        void addCoinBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Controls.AddCoinWindow addCnWd = new Controls.AddCoinWindow(databaseName);
            addCnWd.Show();
        }
        
        /// <summary>
        /// Zapisz baze administrator.
        /// </summary>
        void saveDatabase_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Wszystkie karty.
        /// </summary>
        void allCardsBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }


        /// <summary>
        /// Raport Magazynu.
        /// </summary>
        void storageReportBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Controls.oknoWyboruRaportMagazyn _oknoWyboruRaportMagazyn = new Controls.oknoWyboruRaportMagazyn();
            _oknoWyboruRaportMagazyn.Show();
        }

        /// <summary>
        /// Ostatnio używane.
        /// </summary>
        void recentlyUsedBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Rejestracja.
        /// </summary>
        void registerBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// O programie.
        /// </summary>
        void aboutBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Importuje bazę danych.
        /// </summary>
        void importDatabaseBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Komenda do obsługi przycisku "Eksportuj".
        /// </summary>
        void eksportBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Pobier plik bazy danych z serwera.
        /// </summary>
        void downloadDatabaseBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            WebClient wc = new WebClient();
            string plikDoUploada = "ftp://ftp.goldidea.pl/domains/goldidea.pl/public_html/UploadPath/t.txt";
            if (!Directory.Exists("C:\\Download"))
                Directory.CreateDirectory("C:\\Download");
            Controls.ProgressBar _ProgressBar = new Controls.ProgressBar();
            _ProgressBar.wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(_ProgressBar.wc_DownloadProgressChanged);
            _ProgressBar.tbInportEksport.Text = "Trwa pobieranie pliku";
            _ProgressBar.tbNazwaPliku.Text = "t.txt";
            _ProgressBar.Show();
            wc.DownloadFileAsync(new Uri(plikDoUploada), @"C:\Download\" + "t.txt");
        }

        /// <summary>
        /// Wrzuca plik bazy danych na serwer.
        /// </summary>
        void uploadDatabaseBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            FileUploader.UploadFiles("C:\\t.txt", "ftp://ftp.goldidea.pl//domains//goldidea.pl//public_html//UploadPath//t.txt", "ma5260", "yfcdz2if");
        }

        void reportBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Controls.oknoWyboruRaportu _oknoWyboruRaportu = new Controls.oknoWyboruRaportu();
            _oknoWyboruRaportu.Show();
        }

        void settings_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Controls.ustawienia_wybor _ustawienia_wybor = new Controls.ustawienia_wybor();
            _ustawienia_wybor.AddItemCallback = new AddItemDelegate(this.AddItemCallbackFn);
            _ustawienia_wybor.Show();
        }

        /// <summary>
        /// Drukowanie.
        /// </summary>
        void print_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Kosz.RaportDrawing rpt = new Kosz.RaportDrawing();
            rpt.Show();
        }

        void printPreview_Executed(object sender, ExecutedRoutedEventArgs e)
        {

        }

        /// <summary>
        /// Wyświetla pomoc.
        /// </summary>
        void showHelp_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Controls.Helper _Helper = new Controls.Helper();
            _Helper.Show();
        }

        /// <summary>
        /// Zapisywanie pliku bazy danych.
        /// </summary>
        void saveFile_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            saveDialog.CreatePrompt = true;
            saveDialog.OverwritePrompt = true;
            saveDialog.FileName = "Data";
            saveDialog.DefaultExt = "dat";
            saveDialog.Filter = "Baza Monet (*.DAT)|*.dat";

            if ((bool)saveDialog.ShowDialog())
            {
                System.Data.SQLite.SQLiteConnection.CreateFile(saveDialog.FileName);
            }
        }

        /// <summary>
        /// Kończy działanie aplikacji.
        /// </summary>
        void closeApplication_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// Tworzenie nowego pliku bazy danych.
        /// </summary>
        void newFile_Executed(object sender, ExecutedRoutedEventArgs e)
        {

            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            saveDialog.CreatePrompt = false;
            saveDialog.OverwritePrompt = true;
            saveDialog.FileName = "NewData";
            saveDialog.DefaultExt = "dat";
            saveDialog.Filter = "Baza Monet (*.DAT)|*.dat";

            TreeViewItem catalog = new TreeViewItem();
            catalog.Tag = true;
            catalog.Header = "Katalog Monet";
            CoinTree.Items.Add(catalog);

            SQLite db = new SQLite();

            if ((bool)saveDialog.ShowDialog())
            {
                try
                {
                    if (File.Exists(saveDialog.FileName))
                        File.Delete(saveDialog.FileName);
                    db.OpenDatabase(saveDialog.FileName);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCategoryTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsImageTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsItemTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinNotesTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsPricesTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsPricesYearTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsTypeTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsTypeConvTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateCoinsPricesQuarterTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateConfigTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateStateTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateStatusTableQuerry);
                    db.ExecuteNonQuery(DatabaseQuerries.CreateSubcategoryTableQuerry);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Błąd!", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                databaseName = saveDialog.FileName;
                Controls.AddCoinWindow _AddCoinWindow = new Controls.AddCoinWindow(saveDialog.FileName);
                _AddCoinWindow.Show();
                // InfoBox.Text = databaseName;
            }

            CoinTree.Items.Clear();
            EnableSaving(); // Ustawia możliwośc zapisu pliku. Ta metoda musi zostać wywołana na końcu.
        }

        /// <summary>
        /// Otwieranie nowego pliku bazy danych.
        /// </summary>
        void openFile_Executed(object sender, ExecutedRoutedEventArgs e)
        {   
            CoinTree.Items.Clear();
            OpenFileDialog openDialog = new OpenFileDialog();
            openDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            openDialog.Filter = "Baza Monet (*.DAT)|*.dat";
            openDialog.FilterIndex = 1;
            openDialog.Multiselect = false;

            if ((bool)openDialog.ShowDialog())
            {
                try
                {
                    databaseName = openDialog.FileName;
                    EnableSaving(); //Ustawia możliwość zapisu pliku.
                    TreeViewItem catalog = new TreeViewItem();
                    catalog.Tag = true;
                    catalog.Header = "Katalog Monet";
                    List<string> names = new List<string>();
                    using (SQLiteConnection sqlConnection = new SQLiteConnection())
                    {
                        sqlConnection.ConnectionString = "Data source = " + databaseName + ";";
                        sqlConnection.Open();

                        using (SQLiteCommand sqlCommand = new SQLiteCommand(sqlConnection))
                        {
                            sqlCommand.CommandText = "Select * From category";
                            SQLiteDataReader sqlReader = sqlCommand.ExecuteReader();

                            while (sqlReader.Read())
                            {
                                names.Add((string)sqlReader.GetValue(1));
                            }
                        }

                        int recordCount = 1;
                        foreach (string strResult in names)
                        {
                            List<string> subNames = new List<string>();
                            TreeViewItem item = new TreeViewItem();
                            item.Header = strResult;
                            item.Tag = true;
                            catalog.Items.Add(item);
                            using (SQLiteCommand sqlCommand = new SQLiteCommand(sqlConnection))
                            {
                                sqlCommand.CommandText = "Select * From subcat Where id_cat = '" + recordCount + "'";
                                SQLiteDataReader sqlReader = sqlCommand.ExecuteReader();

                                while (sqlReader.Read())
                                {
                                    subNames.Add((string)sqlReader.GetValue(2));
                                }
                            }
                            recordCount++;


                            foreach (string subStrResult in subNames)
                            {
                                TreeViewItem subItem = new TreeViewItem();                                
                                subItem.Header = subStrResult;
                                item.Items.Add(subItem);
                            }
                        }
                        CoinTree.Items.Add(catalog);
                        sqlConnection.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Błąd!", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        /// <summary>
        /// Akcesor zawierający lokalizację bazy.
        /// </summary>
        public string DATABASE
        {
            get { return databaseName; }
        }

        /// <summary>
        /// Metoda która kontroluje możliwość zapisywania plików, kiedy nie utworzymy bądź otworzymy pliku nie umożliwi nam zapisu.
        /// </summary>
        private void EnableSaving()
        {
            if (!canBeSaved)
            {
                canBeSaved = true;
                this.CommandBindings.Add(saveFileBinding);
            }
        }

        private void LoadCoins()
        {
            SQLiteDataReader sqlReader = Database.wszystko("");
            while (sqlReader.Read())
            {
                string[] tabLat;
                string[] tabCeny;
                SQLiteCommand sqlCommand2 = new SQLiteCommand(Database.connection(""));
                SQLiteDataReader sqlReader2 = Database.reader(@"SELECT id_coin_price_year, id_coin, year, price, rec_status FROM  coins_prices_year WHERE  (id_coin = " + Convert.ToInt32(sqlReader.GetValue(0).ToString()) + ")");
                tabLat = new string[100];
                tabCeny = new string[100];
                int licznikLat = 0;
                while (sqlReader2.Read())
                {
                    tabLat[licznikLat] = sqlReader2.GetValue(2).ToString();
                    tabCeny[licznikLat] = sqlReader2.GetValue(3).ToString();
                    licznikLat++;
                }

                System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.SystemIdle, (System.Threading.ThreadStart)delegate
                {
                    loadedCoins.Insert(0, new Coin(sqlReader.GetValue(3).ToString(), 
                        (byte[])sqlReader.GetValue(23),
                        Tools.CutDate(sqlReader.GetValue(4).ToString()),
                        Convert.ToInt32(sqlReader.GetValue(5).ToString()),
                        sqlReader.GetValue(6).ToString(),
                        sqlReader.GetValue(7).ToString(),
                        sqlReader.GetValue(8).ToString(),
                        sqlReader.GetValue(9).ToString(),
                        sqlReader.GetValue(10).ToString(),
                        sqlReader.GetValue(11).ToString(),
                        sqlReader.GetValue(12).ToString(),
                        sqlReader.GetValue(3).ToString(),
                        sqlReader.GetValue(13).ToString(),
                        sqlReader.GetValue(14).ToString(),
                        0,
                        Convert.ToDouble(sqlReader.GetValue(15).ToString()),
                        0,
                        Convert.ToDouble(sqlReader.GetValue(27).ToString()),
                        0,
                        0,
                        0,
                        0,
                        sqlReader.GetValue(26).ToString(),
                        sqlReader.GetValue(28).ToString(),
                        sqlReader.GetValue(30).ToString(),
                        sqlReader.GetValue(32).ToString(),
                        sqlReader.GetValue(34).ToString(),
                        sqlReader.GetValue(36).ToString(),
                        sqlReader.GetValue(27).ToString(),
                        sqlReader.GetValue(29).ToString(),
                        sqlReader.GetValue(31).ToString(),
                        sqlReader.GetValue(33).ToString(),
                        sqlReader.GetValue(35).ToString(),
                        sqlReader.GetValue(37).ToString(),
                        sqlReader.GetValue(40).ToString(),
                        sqlReader.GetValue(42).ToString(),
                        sqlReader.GetValue(44).ToString(),
                        sqlReader.GetValue(46).ToString(),
                        sqlReader.GetValue(48).ToString(),
                        sqlReader.GetValue(50).ToString(),
                        sqlReader.GetValue(41).ToString(),
                        sqlReader.GetValue(43).ToString(),
                        sqlReader.GetValue(45).ToString(),
                        sqlReader.GetValue(47).ToString(),
                        sqlReader.GetValue(49).ToString(),
                        sqlReader.GetValue(51).ToString(),
                        "", "",
                        tabLat[0], tabLat[1], tabLat[2], tabLat[3], tabLat[4], tabLat[5],
                        tabCeny[0], tabCeny[1], tabCeny[2], tabCeny[3], tabCeny[4], tabCeny[5]
                        ));
                });
            }
        }


        private void AddItemCallbackFn(int index, int item, bool koniec)
        {
            tablicaCheckBox[index] = item;
        }

        private void AddItemCallbackFnDodajMonete(Coin _loadedCoins)
        {
            loadedCoins.Insert(0, _loadedCoins);
        }

        private void CoinTree_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            TreeViewItem treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;
            if (treeViewItem != null)
            {
                treeViewItem.IsSelected = true;
                e.Handled = true;
                if(treeViewItem.Tag != null)
                    TreeContextMenu.Visibility = System.Windows.Visibility.Visible;
                else
                    TreeContextMenu.Visibility = System.Windows.Visibility.Collapsed;
                
            }
        }

        private void watek_ladowanie_danych_podstawowych()
        {
            Thread trd = new Thread(new ThreadStart(loaded));
            trd.IsBackground = true;
            trd.Priority = ThreadPriority.Highest;
            trd.Start();
        }

        private void loaded()
        {
            System.Windows.Application.Current.Dispatcher.Invoke(
                          System.Windows.Threading.DispatcherPriority.SystemIdle,
                              (System.Threading.ThreadStart)delegate
                              {
                                  LoadCoins();
                              });
        }

        static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
        {
            while (source != null && source.GetType() != typeof(T))
                source = VisualTreeHelper.GetParent(source);
            return source;
        }

    }
}